package com.saint.swipemenulistview.courier;

import android.app.Activity;
import android.text.format.Formatter;
import android.util.Log;
import android.widget.Toast;

import com.saint.swipemenulistview.utils.FileUtil;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.UUID;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import id.zelory.compressor.Compressor;

public class UploadImgUtil {
    private static UploadImgUtil uploadUtil;
    private static final String BOUNDARY = UUID.randomUUID().toString(); // 边界标识
    // 随机生成
    private static final String PREFIX = "--";
    private static final String LINE_END = "\r\n";
    private static final String CONTENT_TYPE = "multipart/form-data"; // 内容类型

    private int readTimeOut = 20 * 1000;
    private int connectTimeOut = 20 * 1000;
    private String CHARSET = "utf-8";

    /**
     * 单例模式获取上传工具类
     *
     * @return
     */
    public static UploadImgUtil getInstance() {
        if (null == uploadUtil) {
            uploadUtil = new UploadImgUtil();
        }
        return uploadUtil;
    }

    public void uploadFile(final File file, final String fileKey, final String RequestURL, final OnUploadResult callBack) {
        if (file == null || (!file.exists())) {
            callBack.onResult(null);
        }

        new Thread() {
            @Override
            public void run() {
                String result = toHttpUploadFile(file, fileKey, RequestURL);
                callBack.onResult(result);
            }
        }.start();
    }


    public void uploadFile(Activity act, String imagePath, String fileKey, String requestUrl, OnUploadResult callBack) {
        File uploadFile = new File(imagePath);
        if (uploadFile == null || (!uploadFile.exists())) {
            callBack.onResult(null);
        } else {
            try {
                if (FileUtil.getFileSize(uploadFile) > 500 * 1024) {
                    uploadFile = new Compressor(act)
                            .setMaxWidth(720)
                            .setMaxHeight(1080)
                            .compressToFile(uploadFile);
                    Log.e("Utils:  ", "压缩图片大小： " + Formatter.formatFileSize(act, uploadFile.length()) + "   路径： " + uploadFile.getAbsolutePath());
                }
                uploadThread(uploadFile, fileKey, requestUrl, callBack);
            } catch (IOException e) {
                e.printStackTrace();
                callBack.onFileError();
            } catch (NullPointerException e) {
                e.printStackTrace();
                callBack.onFileError();
            }
        }

    }

    public void uploadThread(final File file, final String fileKey, final String RequestURL, final OnUploadResult callBack) {
        new Thread() {
            @Override
            public void run() {
                String result = toHttpUploadFile(file, fileKey, RequestURL);
                callBack.onResult(result);
            }
        }.start();
    }

    private String toUploadFile(File file, String fileKey, String RequestURL) {
        try {
            URL url = new URL(RequestURL);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(readTimeOut);
            conn.setConnectTimeout(connectTimeOut);
            conn.setDoInput(true); // 允许输入流
            conn.setDoOutput(true); // 允许输出流
            conn.setUseCaches(false); // 不允许使用缓存
            conn.setRequestMethod("POST"); // 请求方式
            conn.setRequestProperty("connection", "keep-alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);

            /**
             * 当文件不为空，把文件包装并且上传
             */
            DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
            StringBuffer sb = new StringBuffer();
            String params = null;
            /**
             * 这里重点注意： name里面的值为服务器端需要key 只有这个key 才可以得到对应的文件
             * filename是文件的名字，包含后缀名的 比如:abc.png
             */
            sb.append(PREFIX).append(BOUNDARY).append(LINE_END);
            sb.append("Content-Disposition:form-data; name=\"" + fileKey + "\"; filename=\"" + file.getName() + "\"" + LINE_END);
            sb.append("Content-Type:image/pjpeg" + LINE_END); // 这里配置的Content-type很重要的
            // ，用于服务器端辨别文件的类型的
            sb.append(LINE_END);
            params = sb.toString();
            sb = null;

            dos.write(params.getBytes());
            /** 上传文件 */
            InputStream is = new FileInputStream(file);
            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = is.read(bytes)) != -1) {
                dos.write(bytes, 0, len);
            }
            is.close();
            dos.write(LINE_END.getBytes());
            byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes();
            dos.write(end_data);
            dos.flush();
            if (conn.getResponseCode() == 200) {
                InputStream inputStream = conn.getInputStream();
                BufferedReader bufferReader = new BufferedReader(new InputStreamReader(inputStream, CHARSET));
                StringBuffer stringBuffer = new StringBuffer();
                String string = new String();
                while ((string = bufferReader.readLine()) != null) {
                    stringBuffer.append(string);
                }
                return stringBuffer.toString();
            } else {
                return "";
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    private String toHttpUploadFile(File file, String fileKey, String RequestURL) {
        try {
            // Query obj = new Query();
            URL url = new URL(RequestURL);
            HttpURLConnection conn = null;
            if (url.getProtocol().toLowerCase().equals("https")) {
                trustAllHosts();
                conn = (HttpsURLConnection) url.openConnection();
                ((HttpsURLConnection) conn).setHostnameVerifier(DO_NOT_VERIFY);// 不进行主机名确认
            } else {
                conn = (HttpURLConnection) url.openConnection();
            }
            conn.setReadTimeout(readTimeOut);
            conn.setConnectTimeout(connectTimeOut);
            conn.setDoInput(true); // 允许输入流
            conn.setDoOutput(true); // 允许输出流
            conn.setUseCaches(false); // 不允许使用缓存
            conn.setRequestMethod("POST"); // 请求方式
            conn.setRequestProperty("connection", "keep-alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);
            /**
             * 当文件不为空，把文件包装并且上传
             */
            DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
            StringBuffer sb = new StringBuffer();
            String params = null;
            /**
             * 这里重点注意： name里面的值为服务器端需要key 只有这个key 才可以得到对应的文件
             * filename是文件的名字，包含后缀名的 比如:abc.png
             */
            sb.append(PREFIX).append(BOUNDARY).append(LINE_END);
            sb.append("Content-Disposition:form-data; name=\"" + fileKey + "\"; filename=\"" + file.getName() + "\"" + LINE_END);
            sb.append("Content-Type:image/pjpeg" + LINE_END); // 这里配置的Content-type很重要的
            // ，用于服务器端辨别文件的类型的
            sb.append(LINE_END);
            params = sb.toString();
            sb = null;

            dos.write(params.getBytes());
            /** 上传文件 */
            InputStream is = new FileInputStream(file);
            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = is.read(bytes)) != -1) {
                dos.write(bytes, 0, len);
            }
            is.close();
            dos.write(LINE_END.getBytes());
            byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes();
            dos.write(end_data);
            dos.flush();

            if (conn.getResponseCode() == 200) {
                InputStream inputStream = conn.getInputStream();
                BufferedReader bufferReader = new BufferedReader(new InputStreamReader(inputStream, CHARSET));
                StringBuffer stringBuffer = new StringBuffer();
                String string = new String();
                while ((string = bufferReader.readLine()) != null) {
                    stringBuffer.append(string);
                }
                return stringBuffer.toString();
            } else {
                return "";
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    static TrustManager[] xtmArray = new MytmArray[]{new MytmArray()};

    static class MytmArray implements X509TrustManager {
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[]{};
        }

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
    }

    ;

    /**
     * 信任所有主机-对于任何证书都不做检查
     */
    private static void trustAllHosts() {
        // Create a trust manager that does not validate certificate chains
        // Android 采用X509的证书信息机制
        // Install the all-trusting trust manager
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, xtmArray, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            // HttpsURLConnection.setDefaultHostnameVerifier(DO_NOT_VERIFY);//
            // 不进行主机名确认
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

    // private String toHttpsUploadFile1(File file, String fileKey, String
    // RequestURL) {
    // String result = "";
    // Query obj = new Query();
    // HttpURLConnection http = null;
    // URL url;
    // try {
    // url = new URL(httpUrl);
    // // 判断是http请求还是https请求
    // if (url.getProtocol().toLowerCase().equals("https")) {
    // trustAllHosts();
    // http = (HttpsURLConnection) url.openConnection();
    // ((HttpsURLConnection) http).setHostnameVerifier(DO_NOT_VERIFY);//
    // 不进行主机名确认
    // } else {
    // http = (HttpURLConnection) url.openConnection();
    // }
    // http.setConnectTimeout(10000);// 设置超时时间
    // http.setReadTimeout(50000);
    // http.setRequestMethod("POST");// 设置请求类型为post
    // http.setDoInput(true);
    // http.setDoOutput(true);
    // http.setRequestProperty("Content-Type", "text/xml");
    // http.setRequestProperty("Cookie", DataDefine.mCookieStore);
    // DataOutputStream out = new DataOutputStream(http.getOutputStream());
    // out.writeBytes(base64);
    // out.flush();
    // out.close();
    // obj.setHttpStatus(http.getResponseCode());// 设置http返回状态200还是403
    // BufferedReader in = null;
    // if (obj.getHttpStatus() == 200) {
    // getCookie(http);
    // in = new BufferedReader(new InputStreamReader(
    // http.getInputStream()));
    // } else
    // in = new BufferedReader(new InputStreamReader(
    // http.getErrorStream()));
    // result = in.readLine();// 得到返回结果
    // in.close();
    // http.disconnect();
    // } catch (Exception e) {
    // // TODO Auto-generated catch block
    // e.printStackTrace();
    // }
    // }}

    public interface OnUploadResult {
        void onResult(String result);

        void onFileError();
    }

}
